package com.ylyq.ylxx.intercepter;

import com.ylyq.ylxx.constants.ExceptionEnum;
import com.ylyq.ylxx.constants.ShiroConstant;
import com.ylyq.ylxx.context.FilterContextHandler;
import com.ylyq.ylxx.model.UserToken;
import com.ylyq.ylxx.util.JwtUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * 用户信息拦截器
 */
@Slf4j
public class AuthIntercepter extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        request.setCharacterEncoding("UTF-8");
//        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        if(request.getMethod().equals(RequestMethod.OPTIONS.name()))
        {
            response.setStatus(HttpStatus.OK.value());
            return false;
        }


        String token = request.getHeader(ShiroConstant.TOKEN);
        String tokenType = request.getHeader(ShiroConstant.TOKEN_TYPE);

        if(StringUtils.isBlank(token)||StringUtils.isBlank(tokenType)){
            log.debug("jwt Token 不存在：{}", token);
            outString(response,ExceptionEnum.TOKEN_TYPE_ERROR.getCode(), ExceptionEnum.TOKEN_TYPE_ERROR.getMsg());
            return false;
        }

        // TODO 从网关获取并校验,通过校验就可信任x-client-token-user中的信息
        UserToken userToken =null;
        try {
            userToken = JwtUtils.getInfoFromToken(token,ShiroConstant.JWT_PRIVATE_KEY + tokenType);
        }catch (SignatureException e){
            log.debug("jwt accessToken或Type值不对 ：{}", token);
            outString(response,ExceptionEnum.TOKEN_OR_TYPE_ERROR.getCode(), ExceptionEnum.TOKEN_OR_TYPE_ERROR.getMsg());
            return false;
        }catch (ExpiredJwtException e){
            log.debug("jwt accessToken 过期：{}", token);
            outString(response, ExceptionEnum.TOKEN_EXPIRE.getCode(), ExceptionEnum.TOKEN_EXPIRE.getMsg());
            return false;
        }catch (Exception e){
            log.debug("jwt accessToken或Type值不对 ：{}", token);
            outString(response,ExceptionEnum.TOKEN_OR_TYPE_ERROR.getCode(), ExceptionEnum.TOKEN_OR_TYPE_ERROR.getMsg());
            return false;
        }

        if(userToken==null){
            log.debug("jwt accessToken 过期：{}", token);
            outString(response, ExceptionEnum.TOKEN_EXPIRE.getCode(), ExceptionEnum.TOKEN_EXPIRE.getMsg());
            return false;
        }
        FilterContextHandler.setToken(token);
        FilterContextHandler.setUsername(userToken.getUsername());
        FilterContextHandler.setUserID(userToken.getUserId());
        FilterContextHandler.setTokenType(tokenType);
        return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        FilterContextHandler.remove();
        super.afterCompletion(request, response, handler, ex);
    }

    private void outString(HttpServletResponse response,int code,String str){
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.setStatus(code);
            PrintWriter out = response.getWriter();
            out.print(str);
            log.info(str);
        } catch (Exception e) {
            log.error("写字符串异常");
        }
    }
}
